#include "GBufferRenderPass.h"
#include <SEngine/Render/RenderFeature/ModelRenderFeature.h> 
#include <SEngine/Render/Descriptors/SceneDescriptor.h>
#include <SERender/Renderer/Renderer.h>
#include <SECore/Ecs/Scene.h>
#include <SEngine/Ecs/Components/ModelRenderComp.h>
#include <SERender/Descriptors/FrameDescriptor.h>
#include <SEDRPPlugin/GBuffer.h>
#include <SEUi/Util/Util.h>
#include <SEUi/SEUi.h>
#include <SERender/Resourses/Loader/ShaderLoader.h>
#include <SEngine/Render/RenderFeature/UBORenderFeature.h>

namespace SEngine
{

    GBufferRenderPass::GBufferRenderPass(Renderer &renderer)
        : RenderPass(renderer)
    {
        m_gBufferShader = Manager::GetInstance().Get<Shader>("GBuffer2").value();
        m_fbo = std::make_unique<FrameBuffer>();
    }

    void GBufferRenderPass::BeginFrame()
    {
    }

    void GBufferRenderPass::DrawFrame()
    {
        auto scene = m_renderer.AnyDescriptor::GetDescriptor<SceneDescriptor>()->get().scene;
        auto & gbuffer = m_renderer.AnyDescriptor::GetDescriptor<GBuffer>()->get();
        auto & frame = m_renderer.AnyDescriptor::GetDescriptor<FrameDescriptor>()->get();
        auto & modelFeature = m_renderer.Descriptor<RenderFeature>::GetDescriptor<ModelRenderFeature>()->get();

        // 获取PBR渲染基础数据
        m_renderer.UseFrameBuffer(*m_fbo, [&]() {
            m_fbo->ClearAttachments();
            m_fbo->SwapAttachments(Attachment::COLOR_ATTACHMENT0, *gbuffer["PositionMetalRT"]);
            m_fbo->SwapAttachments(Attachment::COLOR_ATTACHMENT1, *gbuffer["AlbedoRoughRT"]);
            m_fbo->SwapAttachments(Attachment::COLOR_ATTACHMENT2, *gbuffer["NormalDepthRT"]);
            m_fbo->EnableRenderBuffer(true);
            m_fbo->Resize(frame.w, frame.h);
            m_fbo->Use();
            m_renderer.GetDrive()->Clear(COLOR_BUFFER_BIT | DEPTH_BUFFER_BIT);
            scene->Components<ModelRenderComp>([&](Actor & actor, ModelRenderComp & comp) {
                modelFeature.DrawModel(comp.m_model, m_gBufferShader);
            });
        });

        // 初始化ShadowMap
        // m_renderer.UseFrameBuffer(*m_fbo, [&]() {
        //     m_fbo->ClearAttachments();
        //     m_fbo->SwapAttachments(Attachment::COLOR_ATTACHMENT0, *gbuffer["ShadowMapRT"]);
        //     m_fbo->EnableRenderBuffer(true);
        //     m_fbo->Resize(frame.w, frame.h);
        //     m_fbo->Use();
        //     m_renderer.GetDrive()->Clear(COLOR_BUFFER_BIT);
        // });

        // gbuffer.Foreach([](std::string name, auto tex) {
        //     ShowRT(name, tex->GetId());
        // });
        
        SignalUpdateUI.AddSlot([this]() {
            ImGui::PushID("GBufferRenderPass");
            if (ImGui::CollapsingHeader("GBufferRenderPass")) {
                if (ImGui::Button("Reload")) {
                    m_gBufferShader.Reload([](auto & path, auto & name) {
                        ShaderLoader loader;
                        return loader.Load(path).CreateShader(EngineUniformBlockBinder());
                    });
                }
            }
            ImGui::PopID();
            return SlotState::Once;
        });
    }

} // namespace SEngine
